import org.junit.Test;

public class Solution10 {
    /**
     * 给你一个字符串 s 和一个字符规律 p，请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
     * <p>
     * '.' 匹配任意单个字符
     * '*' 匹配零个或多个前面的那一个元素
     * 所谓匹配，是要涵盖 整个 字符串 s的，而不是部分字符串
     * <p>
     * 输入:
     * s = "aa"
     * p = "a*"
     * 输出: true
     * 解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此，字符串 "aa" 可被视为 'a' 重复了一次。
     */
    public boolean isMatch(String s, String p) {
        return isMatchCore(s, p, 0, 0);
    }

    private boolean isMatchCore(String s, String p, int indexS, int indexP) {
        if (indexS == s.length() && indexP == p.length()) return true;
        if (indexS < s.length() && indexP == p.length()) return false;
        //p串的下一个是*
        if (indexP + 1 < p.length() && p.charAt(indexP + 1) == '*') {
            //当前字符匹配成功
            if (indexS < s.length() && (s.charAt(indexS) == p.charAt(indexP) || p.charAt(indexP) == '.')) {
                return isMatchCore(s, p, indexS + 1, indexP + 2)
                        || isMatchCore(s, p, indexS + 1, indexP)
                        || isMatchCore(s, p, indexS, indexP + 2);
            } else {
                return isMatchCore(s, p, indexS, indexP + 2);
            }
        }
        //p串的下一个不是*
        if (indexS < s.length() && (s.charAt(indexS) == p.charAt(indexP) || p.charAt(indexP) == '.')) {
            return isMatchCore(s, p, indexS + 1, indexP + 1);
        }
        return false;
    }


    public boolean isMatch2(String s, String p) {
        int m = s.length();
        int n = p.length();

        boolean[][] f = new boolean[m + 1][n + 1];
        f[0][0] = true;
        for (int i = 0; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (p.charAt(j - 1) == '*') {
                    f[i][j] = f[i][j - 2];
                    if (matches(s, p, i, j - 1)) {
                        f[i][j] = f[i][j] || f[i - 1][j];
                    }
                }
                else {
                    if (matches(s, p, i, j)) {
                        f[i][j] = f[i - 1][j - 1];
                    }
                }
            }
        }
        return f[m][n];
    }

    public boolean matches(String s, String p, int i, int j) {
        if (i == 0) {
            return false;
        }
        if (p.charAt(j - 1) == '.') {
            return true;
        }
        return s.charAt(i - 1) == p.charAt(j - 1);
    }


    @Test
    public void test(){
        float f = 11.9f;
        int i = Float.floatToIntBits(f);
        System.out.println(f);
        System.out.println(Integer.toBinaryString(i));
    }
}
